Skip to content

Conversation

@rodrigobr-msft
Copy link
Contributor

This pull request refactors the TypingIndicator class in typing_indicator.py to replace its asynchronous, asyncio-based implementation with a simpler threading-based approach using threading.Timer. The main goal is to simplify the logic for sending "typing" activities by removing the complexity of managing asynchronous tasks and locks.

Key changes:

Refactoring from asyncio to threading:

  • Replaced the use of asyncio, including tasks and locks, with threading.Timer for scheduling typing indicator events. This removes the need for async task management and simplifies the class. [1] [2]
  • The start method now uses threading.Timer to schedule typing events and is no longer protected by an async lock.
  • The stop method is now synchronous and cancels the timer directly, instead of cancelling an asyncio task.

Class interface and logic changes:

  • The interval parameter is now in milliseconds (default 10ms) and is stored as _interval.
  • The internal typing loop is replaced by a timer callback function (_on_timer), which sends the typing activity and handles errors and stopping logic.

These changes make the typing indicator logic easier to maintain and less error-prone by avoiding complex async patterns.

Copilot AI review requested due to automatic review settings October 29, 2025 21:33
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the TypingIndicator class from an asyncio-based implementation to a threading-based implementation using threading.Timer. The main changes include replacing the continuous asyncio task loop with a single-shot timer and simplifying the start/stop logic.

  • Changed from asyncio-based task management to threading-based Timer
  • Replaced continuous loop with single timer execution
  • Changed default interval from 1 second to 10 units (with unit mismatch in log message)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

async with self._lock:
if not self._running:
return
logger.debug(f"Starting typing indicator with interval: {self._interval} ms")
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log message states the interval is in milliseconds ('ms'), but Python's threading.Timer expects the interval in seconds. The interval value should be documented correctly or converted appropriately.

Suggested change
logger.debug(f"Starting typing indicator with interval: {self._interval} ms")
logger.debug(f"Starting typing indicator with interval: {self._interval} seconds")

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +37
func = self._on_timer(context)
self._timer = Timer(self._interval, func)
self._timer.start()
await func()
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Timer is created with an async function but Timer expects a synchronous callable. When the timer expires, it will try to call the async function synchronously, which will not execute the coroutine properly. Additionally, the timer only fires once and won't send recurring typing indicators as the original implementation did.

Copilot uses AI. Check for mistakes.
self._timer.start()
await func()

def stop(self) -> None:
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stop method signature changed from async def to def, but it's still called with await typing.stop() in agent_application.py line 736. This will cause a runtime error since you cannot await a non-coroutine.

Copilot uses AI. Check for mistakes.
self._running: bool = False
self._lock = asyncio.Lock()
_interval: int
_timer: Optional[Timer] = None
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _timer class attribute will be shared across all instances of TypingIndicator. This should be an instance attribute initialized in __init__ to avoid state being shared between different instances.

Copilot uses AI. Check for mistakes.
async with self._lock:
if self._running:
return
def __init__(self, interval=10) -> None:
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default interval changed from 1 second to 10 seconds without updating call sites. Given the original was 1 second and sent typing indicators continuously in a loop, this significantly changes the behavior and timing characteristics.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants